﻿import win32com.client


def createObject(progId):
    return win32com.client.Dispatch(progId)


class Error(Exception):
    _support_ = createObject("ActSupport.ActMLSupport")

    def __init__(self, error):
        msg = self._support_.GetErrorMessage(error)
        super(Error, self).__init__(msg)


class Base(object):
    def __init__(self, *args):
        self.plc = createObject(self._control_)
        self.isOpen = False
        if 1 == len(args):
            self.plc.ActStationNumber = args[0]
        elif 2 <= len(args):
            self.plc.ActNetworkNumber = args[0]
            self.plc.ActStationNumber = args[1]

    def open(self):
        error = self.plc.Open()
        if error:
            raise Error(error)
        print self.getCpuType()
        self.isOpen = True
        
    def close(self):
        self.plc.Close()
        self.isOpen = False
        
    def getCpuType(self):
        error, cpuName, cpuType = self.plc.GetCpuType()
        if error:
            raise Error(error)
        return cpuName, cpuType

    def __getitem__(self, device):
        error, value = self.plc.GetDevice2(device)
        if error:
            raise Error(error)
        return value

    def __setitem__(self, device, value):
        error = self.plc.SetDevice2(device, value)
        if error:
            raise Error(error)

    def read(self, device, size):
        data = [0]*size
        error, data = self.plc.ReadDeviceBlock2(device, len(data), data)
        if error:
            raise Error(error)
        return list(data)

    def write(self, device, data):
        error = self.plc.WriteDeviceBlock2(device, len(data), data)
        if error:
            raise Error(error)
            
    def readlist(self, devlist):
        device = "\n".join(devlist)
        size = len(devlist)
        data = [0]*size
        error, data = self.plc.ReadDeviceRandom2(device, size, data)
        if error:
            raise Error(error)
        return list(data)
        
    def writelist(self, data):
        device = "\n".join(data.keys())
        data = data.values()
        error = self.plc.WriteDeviceRandom2(device, len(data), data)
        if error:
            raise Error(error)

    def readBuffer(self, startIO, address, size):
        data = [0]*size
        error, data = self.plc.ReadBuffer(startIO, address, len(data), data)
        if error:
            raise Error(error)
        return list(data)

    def writeBuffer(self, startIO, address, data):
        error = self.plc.WriteBuffer(startIO, address, len(data), data)
        if error:
            raise Error(error)
